package com.gsit.expenditure.controller;



import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Set;

import javafx.beans.binding.Bindings;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.StackPane;
import javafx.util.StringConverter;
import javafx.util.converter.IntegerStringConverter;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import org.apache.poi.hssf.record.PageBreakRecord.Break;

import com.gsit.expenditure.client.domina.FXMLBase;
import com.gsit.expenditure.client.domina.VehicleBean;
import com.gsit.expenditure.client.domina.VendorBean;
import com.gsit.expenditure.component.CheckBoxTableCell;
import com.gsit.expenditure.domain.Address;
import com.gsit.expenditure.domain.Customer;
import com.gsit.expenditure.domain.Vehicle;
import com.gsit.expenditure.domain.Vendor;
import com.gsit.expenditure.services.VehicleServices;
import com.gsit.expenditure.services.VendorServices;
import com.gsit.expenditure.utils.AppContextLoader;
import com.gsit.expenditure.utils.Page;
import com.gsit.expenditure.utils.Utils;
import com.gsit.expenditure.utils.ViewHandler;


public class VendorController extends BaseController implements Initializable{
	
	//TABLE
	@FXML
	private TableView<Vehicle> tableViewVehicle;
	@FXML
	private TableColumn<VehicleBean, String> vehicleNameColumn;
	@FXML
	private TableColumn<VehicleBean, String> vehicleNumberColumn;
	@FXML
	private TableColumn<VehicleBean, String> vehicleRateColumn;
		
	
	public List<Vehicle> vehicleList;
	
	//TextFields
	@FXML private TextField firstname;
	@FXML private TextField lastname;
	@FXML private TextField address1;
	@FXML private TextField address2;
	@FXML private TextField city;
	@FXML private TextField state;
	@FXML private TextField country;
	@FXML private TextField pincode;
	
	@FXML private TextField phone;
	@FXML private TextField mobile;
	@FXML private Button saveButton;
	
	//Error labels
	@FXML private Label firstNameErrorLabel;
	@FXML private Label lastnameErrorLabel;
	@FXML private Label addressErrorLabel;
	@FXML private Label mobileErrorLabel;
	@FXML private Label phoneErrorLabel;
	@FXML private Label cityErroLabel;
	@FXML private Label stateErrorLabel;
	@FXML private Label countryErroLabel;
	//@FXML private Label pinErrorLabel;
	

	//validator
	private Validator validator;
	
	@FXML
	private StackPane centerPane;
	private Vendor vendor; 
	private Vehicle veList; 
	private VendorBean vendorBean;  
	private VendorServices services;
	private List<Vendor> vendorList;
	
	
	@Override
	public void initialize(URL url, ResourceBundle bundle) {
		services=AppContextLoader.getBean(VendorServices.class);
		AppContextLoader.getBean(VehicleServices.class);
		vendorBean=new VendorBean(null);
		bind();
		initTable();
	}
	
	private void bind(){
		Bindings.bindBidirectional(vendorBean.getFirstName(),firstname.textProperty());
		Bindings.bindBidirectional(vendorBean.getLastName(),lastname.textProperty());
	
		Bindings.bindBidirectional(vendorBean.getAddress1(),address1.textProperty());
		Bindings.bindBidirectional(vendorBean.getAddress2(),address2.textProperty());
		Bindings.bindBidirectional(vendorBean.getCity(),city.textProperty());
		Bindings.bindBidirectional(vendorBean.getState(),state.textProperty());
		Bindings.bindBidirectional(vendorBean.getCountry(),country.textProperty());
		StringConverter integerConverter = new IntegerStringConverter();
		Bindings.bindBidirectional(pincode.textProperty(), vendorBean.getPincode(), integerConverter);
		Bindings.bindBidirectional(vendorBean.getPhone(),phone.textProperty());
		Bindings.bindBidirectional(vendorBean.getMobile(),mobile.textProperty());
			
	}
	
	@Override
	public void onSave() {
		Boolean isUpdate = Boolean.FALSE;
		if (isValid()) {
			/* if (vendor.getId() != null && vendor.getId().longValue() > 0) { */
			isUpdate = Boolean.TRUE;

			if (isValid()) {
				Vendor vendor = vendorBean.getObject();
				if (vendor != null && vendor.getId() != null && vendor.getId().longValue() > 0) {
					isUpdate = Boolean.TRUE;
					vendor.setModifiedDate(Utils.getCurrentDate());
					//vendor.setVersion(1L);
					services.saveOrUpdate(vendor);
					} else {
					vendor.setCreatedDate(Utils.getCurrentDate());
					vendor.setModifiedDate(Utils.getCurrentDate());
					//vendor.setVersion(1L);
					vendor = services.saveOrUpdate(vendorBean.getObject());
					if (vendor.getId() != null) {
						showCustomerPopup(vendor);
					}
				}
				if (isUpdate) {
					stateChange.set(Boolean.TRUE);
				}
				onClear();
			}
		}
	}
	//}
	private void init(){
		if (this.vendorBean.getFirstName()==null) return;
		this.vendor=this.vendorBean.getVendor();
		firstname.setText(vendor.getFirstName());
		lastname.setText(vendor.getLastName());
		Address address=new Address();
		address1.setText(address.getAddress1());
		address2.setText(address.getAddress2());
		city.setText(address.getCity());
		state.setText(address.getState());
		country.setText(address.getCountry());
		pincode.setText(address.getPinCode());
		phone.setText(vendor.getPhone());
		mobile.setText(vendor.getMobile());
	}
	
	//INIT TABLE 
	public void initTable(){
		vehicleNameColumn.setCellValueFactory(new PropertyValueFactory<VehicleBean, String>("vehicleName"));
		vehicleNumberColumn.setCellValueFactory(new PropertyValueFactory<VehicleBean, String>("vehicleNumber"));
		vehicleRateColumn.setCellValueFactory(new PropertyValueFactory<VehicleBean, String>("rate"));
	}
	
	@Override
	public void onClear(){
		System.out.println(">>>>>>. onClear >>>>>>>");
		vendorBean.clean();
	}
	public void reLoad(VendorBean vendorBean) {
		this.vendorBean=vendorBean;
		init();
		bind();
	}
	

	
	@FXML
	public void addVehicle(){
		
		showVehicleTable();
		
		ObservableList<Vehicle> vehicles = tableViewVehicle.getItems();
		System.out.println("ObservableList size :: "+vehicles.size());
		Set<Vehicle> vehiclesSet = (Set<Vehicle>) CheckBoxTableCell.getSelectedItemSet();
		
		if(vehicles!= null && vehicles.size() == 0){
			vehicles.addAll(vehiclesSet);
		}
		
		else {
			for (Vehicle vehicleSet : vehiclesSet) {
				for (Vehicle vehicleTable : vehicles) {
					if (!vehicleTable.getVehicleNumber().equals(vehicleTable.getVehicleNumber())) {
						vehicles.add(vehicleTable);
					}
				}

			}

		}
		CheckBoxTableCell.setSelectedItemSet(null);
	}
	 

			
		
	
	private void showVehicleTable() {
		
		final FXMLBase<VehicleListController> fxmlBase =  ViewHandler.createFXMLBase(Page.VEHICLE_LIST);
		fxmlBase.getController().getStateChange().addListener(new ChangeListener<Boolean>() {
			@Override
			public void changed(ObservableValue<? extends Boolean> arg0,Boolean oldVal, Boolean newVal) {
				System.out.println(">>>>>>>>>>>>>>>>>>>>>>>called ");
				if(newVal){
					fxmlBase.getDialogStage().hide();
				}
			}
		});
		ViewHandler.createDialog(fxmlBase, "List of Vehicles");
		fxmlBase.getDialogStage().showAndWait();
		
	}

	private Boolean isValid(){
		clearAllErrorLabels();
		Boolean result =Boolean.TRUE;
		
		validator = Validation.buildDefaultValidatorFactory().getValidator();
		
		Set<ConstraintViolation<Vendor>> constraintViolations=validator.validate(vendorBean.getObject());
		if (constraintViolations.size() > 0) {
			for (ConstraintViolation<Vendor> constraintViolation : constraintViolations) {
				if("firstName".equalsIgnoreCase(constraintViolation.getPropertyPath().toString())){
					firstNameErrorLabel.setText(constraintViolation.getMessage());
					result = Boolean.FALSE;
				}
				
				if("address.address1".equalsIgnoreCase(constraintViolation.getPropertyPath().toString())){
					addressErrorLabel.setText(constraintViolation.getMessage());
					result = Boolean.FALSE;
				}
				if("address.city".equalsIgnoreCase(constraintViolation.getPropertyPath().toString())){
					cityErroLabel.setText(constraintViolation.getMessage());
					result = Boolean.FALSE;
				}
				if("address.state".equalsIgnoreCase(constraintViolation.getPropertyPath().toString())){
					stateErrorLabel.setText(constraintViolation.getMessage());
					result = Boolean.FALSE;
				}
				if("address.country".equalsIgnoreCase(constraintViolation.getPropertyPath().toString())){
					countryErroLabel.setText(constraintViolation.getMessage());
					result = Boolean.FALSE;
				}
				if("mobile".equalsIgnoreCase(constraintViolation.getPropertyPath().toString())){
					mobileErrorLabel.setText(constraintViolation.getMessage());
					result = Boolean.FALSE;
				}
				if("phone".equalsIgnoreCase(constraintViolation.getPropertyPath().toString())){
					phoneErrorLabel.setText(constraintViolation.getMessage());
					result = Boolean.FALSE;
				}
			}
		}
		
		return result;
	}
	
private void clearAllErrorLabels(){
	     firstNameErrorLabel.setText("");
	     addressErrorLabel.setText("");
	     mobileErrorLabel.setText("");
	     cityErroLabel.setText("");
		 stateErrorLabel.setText("");
		 countryErroLabel.setText("");
		 phoneErrorLabel.setText("");
	}

private void showCustomerPopup(Vendor vendor){
	final FXMLBase<SuccessController> fxmlBase =  ViewHandler.createFXMLBase(Page.SUCCESS_MSG);
	fxmlBase.getController().getStateChange().addListener(new ChangeListener<Boolean>() {
		@Override
		public void changed(ObservableValue<? extends Boolean> arg0,Boolean oldVal, Boolean newVal) {
			if(newVal){
				fxmlBase.getDialogStage().hide();
			}
		}
	});
	ViewHandler.createDialog(fxmlBase, "Informations has been successfully created");
	fxmlBase.getDialogStage().showAndWait();
}

}
